package data

import (
	"context"
	"shop-demo/app/product/service/internal/biz"
)

type productRepo struct {
	data *Data
}

func NewProductRepo(data *Data) biz.ProductRepo {
	return &productRepo{
		data: data,
	}
}

func (p *productRepo) CreateProduct(ctx context.Context, product *biz.Product) (*biz.Product, error) {
	saved, err := p.data.db.Product.Create().SetName(product.Name).SetNum(product.Num).Save(ctx)
	if err != nil {
		return nil, err
	}
	return &biz.Product{
		Id:   saved.ID,
		Name: saved.Name,
		Num:  saved.Num,
	}, nil
}

func (p *productRepo) UpdateProduct(ctx context.Context, product *biz.Product) (*biz.Product, error) {
	saved, err := p.data.db.Product.UpdateOneID(product.Id).SetNum(product.Num).Save(ctx)
	if err != nil {
		return nil, err
	}
	return &biz.Product{
		Id:   saved.ID,
		Name: saved.Name,
		Num:  saved.Num,
	}, nil
}

func (p *productRepo) DeleteProduct(ctx context.Context, id int64) error {
	err := p.data.db.Product.DeleteOneID(id).Exec(ctx)
	return err
}

func (p *productRepo) GetProduct(ctx context.Context, id int64) (*biz.Product, error) {
	product, err := p.data.db.Product.Get(ctx, id)
	if err != nil {
		return nil, err
	}
	return &biz.Product{
		Id:   product.ID,
		Name: product.Name,
		Num:  product.Num,
	}, nil
}

func (p *productRepo) ListProduct(ctx context.Context, pageNum int64, pageSize int64) ([]*biz.Product, error) {
	products, err := p.data.db.Product.Query().Limit(int(pageSize)).Offset(int(pageNum - 1*pageSize)).All(ctx)
	if err != nil {
		return nil, err
	}
	result := make([]*biz.Product, 0, len(products))

	for _, product := range products {
		result = append(result, &biz.Product{
			Id:   product.ID,
			Name: product.Name,
			Num:  product.Num,
		})
	}
	return result, nil
}
